﻿/*********************************************************************
 * @file       mainwindow.cpp
 * @brief      程序运行主窗口类
 * @details    基于ui文件运行
 * @author     南樟(a2169272059@163.com)
 * @date       2025-2-10
 * @version    1.0.0
 * @copyright  a2169272059@163.com
 *********************************************************************/
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QStackedWidget>
#include <QDebug>
#include <QDate>
#include <QMessageBox>

#include "sqlite.h"
#include "week_block.h"
#include "dayly_block.h"
#include "ticktimer.h"
#include "week_minblock.h"
#include "clock_block.h"
#include "create_dayly.h"
#include "create_clock.h"
#include "create_week.h"
/// 数据库对象类
sqlite db;
/// 主窗口堆叠stackedWidget
QStackedWidget *g_mainWidget;
/// 主滴答触发器
extern tickTimer *g_ticker;
/**
 * @brief MainWindow::MainWindow 程序运行主窗口的构造函数
 * @param parent 父节点
 */
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 设置 QDockWidget 内部内容区域的边框
    ui->dockWidget->setStyleSheet(
        "QDockWidget {"
        "   border: none;"
        "}"
        "QDockWidget > QWidget {"
        "   border-right: 1px solid lightgray;"  // 只设置右边框
        "   border-bottom: 1px solid lightgray;" // 只设置底边框
        "   padding: 0px;"                      // 确保没有额外的内边距
        "}"
    );
    // 切换到主界面
    g_mainWidget = ui->stackedWidget;
    ui->stackedWidget->setCurrentIndex(index_main);
    ui->toolBox->setCurrentIndex(index_main);
}
/**
 * @brief MainWindow::~MainWindow 程序运行主窗口的析构函数
 */
MainWindow::~MainWindow()
{
    delete ui;
}
/**
 * @brief MainWindow::on_toolBox_currentChanged 在左停靠框切换界面的逻辑
 * @param index 切换界面的id
 * @note 这里确保index编号和stacked中的变换顺序一致
 * @see enum page_index
 */
void MainWindow::on_toolBox_currentChanged(int index)
{
    // 还有on_stackedWidget_currentChanged里面的逻辑
    ui->stackedWidget->setCurrentIndex(index);
}
/**
 * @brief MainWindow::update_clock 闹钟界面动态更新的逻辑
 * @return 执行情况
 *  @retval true 执行成功
 *  @retval false 执行失败
 */
bool MainWindow::update_clock()
{
    if(!db.createTable_clock()){
        return false;
    }
    QWidget *contentWidget = ui->clockContents;
    QVBoxLayout *layout =qobject_cast<QVBoxLayout*>(contentWidget->layout());
    if(!layout){
        layout = new QVBoxLayout(contentWidget);
        layout->setAlignment(Qt::AlignTop);
        contentWidget->setLayout(layout);
    }else{
        QLayoutItem *item;
        while((item = layout->takeAt(0))!=nullptr){
            delete item->widget();
            // 删除布局项
            delete item;
        }
    }
    // 添加新组件到内容小部件的布局中
    QSqlQuery query(db.get_db());
    bool success = query.exec("SELECT id,note,clock_time,enable,bits_week FROM clock");
    if(!success){
        qDebug()<<"闹钟块动态生成失败"<<query.lastError();
        return false;
    }
    while(query.next()){
        // qDebug()<<"0: "<<query.value(0).toInt();
        // qDebug()<<"1: "<<query.value(1).toString();
        // qDebug()<<"2: "<<query.value(2).toString();
        // qDebug()<<"3: "<<query.value(3).toInt();
        clock_block *it = new clock_block(contentWidget
                                          ,query.value(0).toInt()
                                          ,query.value(1).toString()
                                          ,query.value(2).toString()
                                          ,query.value(3).toInt()
                                          ,query.value(4).toInt());
        layout->addWidget(it);
    }
    // 更新滚动区域以适应新添加的组件
    ui->clockArea->ensureWidgetVisible(contentWidget);
    return true;
}
/**
 * @brief MainWindow::update_week 周表界面动态更新的逻辑
 * @return 执行情况
 *  @retval true 执行成功
 *  @retval false 执行失败
 */
bool MainWindow::update_week()
{
    if(!db.createTable_week_duration()){
        return false;
    }
    QWidget *contentWidget = ui->weekContents;
    // QVBoxLayout 使各单元横向铺平
    QVBoxLayout *layout = qobject_cast<QVBoxLayout*>(contentWidget->layout());
    if(!layout){
        layout = new QVBoxLayout(contentWidget);
        layout->setSpacing(0);
        layout->setContentsMargins(0,0,0,0);
        contentWidget->setLayout(layout);
    }else{
        qDebug()<<"已经建好了数据";
        QLayoutItem *item=layout->takeAt(0);
        QLayout *childLayout = item->layout();
        while(QLayoutItem *childItem = childLayout->takeAt(0)){
            childItem->widget()->deleteLater();
            delete childItem;
        }
        // 删除布局项
        delete item;
    }

    // 更新界面内容
    QDate date = QDate::currentDate();
    ui->lab_dateNoday->setText(QString::asprintf("%d年%d月%d日",date.year(),date.month(),date.day()));
    if(date.dayOfWeek()!=7){
        date = date.addDays(-date.dayOfWeek());
    }
    ui->week_0->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_1->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_2->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_3->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_4->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_5->setText(QString::number(date.day()));
    date = date.addDays(1);
    ui->week_6->setText(QString::number(date.day()));

    QHBoxLayout *minLayout = new QHBoxLayout(contentWidget);
    minLayout->setSpacing(0);
    minLayout->setContentsMargins(0,0,0,0);
    week_block *weekBlock0 = new week_block(contentWidget);
    week_block *weekBlock1 = new week_block(contentWidget);
    week_block *weekBlock2 = new week_block(contentWidget);
    week_block *weekBlock3 = new week_block(contentWidget);
    week_block *weekBlock4 = new week_block(contentWidget);
    week_block *weekBlock5 = new week_block(contentWidget);
    week_block *weekBlock6 = new week_block(contentWidget);
    // 查询
    QSqlQuery query(db.get_db());
    query.prepare("SELECT id,name,on_week,begin_time,end_time "
               "FROM week_duration "
               "WHERE :date >= begin_date AND :date <=end_date");
    query.bindValue(":date",date.toString("yyyy-MM-dd"));
    if(!query.exec()){
        QMessageBox::warning(this,"错误","周表块动态生成失败");
    }
    // 更新数据
    while(query.next()){
        QTime time0 = QTime::fromString(query.value(3).toString(),"HH:mm");
        QTime time1 = QTime::fromString(query.value(4).toString(),"HH:mm");
        switch(query.value(2).toInt()){
        case 7:
            weekBlock0->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock0
                ),time0.minute() + time0.hour()*60
            );
            break;
        case 1:
            weekBlock1->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock1
                    ),time0.minute() + time0.hour()*60
            );
            break;
        case 2:
            weekBlock2->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock2
                                                    ),time0.minute()*2 + time0.hour()*120
                                  );
            break;
        case 3:
            weekBlock3->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock3
                                                    ),time0.minute()*2 + time0.hour()*120
                                  );
            break;
        case 4:
            weekBlock4->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock4
                                                    ),time0.minute()*2 + time0.hour()*120
                                  );
            break;
        case 5:
            weekBlock5->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock5
                                                    ),time0.minute()*2 + time0.hour()*120
                                  );
            break;
        case 6:
            weekBlock6->addWidget(new week_minBlock(query.value(1).toString()
                                                    ,query.value(3).toString()
                                                    ,query.value(4).toString()
                                                    ,time0.secsTo(time1)/30
                                                    ,weekBlock6
                                                    ),time0.minute()*2 + time0.hour()*120
                                  );
            break;
        default:
            qDebug()<<"周表中出现未定义的星期";
            QMessageBox::warning(contentWidget,"警告","每周安排数据中出现未定义的星期");
        }
    }
    weekBlock0->setStyleSheet("background-color: lightgray;");
    weekBlock2->setStyleSheet("background-color: lightgray;");
    weekBlock4->setStyleSheet("background-color: lightgray;");
    weekBlock6->setStyleSheet("background-color: lightgray;");
    minLayout->addWidget(weekBlock0);
    minLayout->addWidget(weekBlock1);
    minLayout->addWidget(weekBlock2);
    minLayout->addWidget(weekBlock3);
    minLayout->addWidget(weekBlock4);
    minLayout->addWidget(weekBlock5);
    minLayout->addWidget(weekBlock6);
    layout->addLayout(minLayout);
    qDebug()<<"styleSheet"<<weekBlock0->styleSheet();

    // 更新滚动区域以适应新添加的组件
    ui->weekArea->ensureWidgetVisible(contentWidget);
    return true;
}
/**
 * @brief MainWindow::update_dayly 日程数据的动态更新逻辑
 * @return 执行情况
 *  @retval true 执行成功
 *  @retval false 执行失败
 */
bool MainWindow::update_dayly()
{
    if(!db.createTable_day_duration()){
        return false;
    }
    QWidget *contentWidget = ui->daylyContents;
    QVBoxLayout *layout =qobject_cast<QVBoxLayout*>(contentWidget->layout());
    if(!layout){
        layout = new QVBoxLayout(contentWidget);
        layout->setAlignment(Qt::AlignTop);
        contentWidget->setLayout(layout);
    }else{
        QLayoutItem *item;
        while((item = layout->takeAt(0))!=nullptr){
            delete item->widget();
            // 删除布局项
            delete item;
        }
    }
    // 添加新组件到内容小部件的布局中
    QSqlQuery query(db.get_db());
    QDate date = QDate::currentDate();

    ui->lab_date->setText(QString::asprintf("%d年%d月%d日",date.year(),date.month(),date.day()));
    qDebug() << "the date is"<<date.toString("yyyy-MM-dd");
    query.prepare("SELECT id,note,begin_time,end_time,begin_date,end_date "
                  "FROM day_duration WHERE begin_date <= :date AND end_date >= :date");
    query.bindValue(":date",date.toString("yyyy-MM-dd"));
    if(!query.exec()){
        qDebug()<<"日程块动态生成失败"<<query.lastError();
        QMessageBox::warning(this,"警告","无法查询到日程数据表");
        return false;
    }
    while(query.next()){
        qDebug()<<"0: "<<query.value(0).toInt();    // id
        qDebug()<<"1: "<<query.value(1).toString(); // note
        qDebug()<<"2: "<<query.value(2).toString(); // begin_time
        qDebug()<<"3: "<<query.value(3).toString(); // end_time
        qDebug()<<"4: "<<query.value(4).toInt();    // begin_date
                                                    // end_date
        dayly_block *it = new dayly_block(contentWidget
                        ,query.value(0).toInt(),query.value(2).toString()
                        ,query.value(3).toString(),query.value(1).toString()
                        ,date.daysTo(QDate::fromString(query.value(5).toString(),"yyyy-MM-dd"))
                        ,QDate::fromString(query.value(4).toString(),"yyyy-MM-dd").daysTo(date));
        layout->addWidget(it);
    }
    // 更新滚动区域以适应新添加的组件
    ui->daylyArea->ensureWidgetVisible(contentWidget);
    return true;
}
/**
 * @brief MainWindow::on_act_addClock_triggered 闹钟添加按钮的逻辑
 */
void MainWindow::on_act_addClock_triggered()
{
    auto tmpWidget = new create_clock(ui->stackedWidget);
    connect(tmpWidget,&create_clock::back2Clock,this,[this,tmpWidget](){
        tmpWidget->deleteLater();
        update_clock();
        g_ticker->load_clock();
        g_ticker->start();
        ui->stackedWidget->setCurrentIndex(index_clock);
    });
    tmpWidget->init();
    ui->stackedWidget->addWidget(tmpWidget);
    ui->stackedWidget->setCurrentWidget(tmpWidget);
}
/**
 * @brief MainWindow::on_stackedWidget_currentChanged 主stacked切换时自动更新的逻辑
 * @param index
 */
void MainWindow::on_stackedWidget_currentChanged(int index)
{
    if(index == index_clock){
        update_clock();
    }else if(index == index_week){
        update_week();
    }else if(index == index_day){
        update_dayly();
    }
}
/**
 * @brief MainWindow::on_act_addDayly_triggered 日程表[添加]按钮的逻辑
 */
void MainWindow::on_act_addDayly_triggered()
{
    auto tmpWidget = new create_dayly(ui->stackedWidget);
    connect(tmpWidget,&create_dayly::back2dayly,this,[this,tmpWidget](){
        tmpWidget->deleteLater();
        ui->stackedWidget->setCurrentIndex(index_day);
    });
    tmpWidget->init();
    ui->stackedWidget->addWidget(tmpWidget);
    ui->stackedWidget->setCurrentWidget(tmpWidget);
}

/**
 * @brief MainWindow::on_act_addWeek_triggered 周表[添加]按钮的逻辑
 */
void MainWindow::on_act_addWeek_triggered()
{
    auto tmpWidget = new create_week(ui->stackedWidget);
    connect(tmpWidget,&create_week::back2Week,this,[this,tmpWidget](){
        tmpWidget->deleteLater();
        ui->stackedWidget->setCurrentIndex(index_week);
    });
    tmpWidget->init();
    ui->stackedWidget->addWidget(tmpWidget);
    ui->stackedWidget->setCurrentWidget(tmpWidget);
}

